# -*- coding: utf-8 -*-
import hashlib
import json

import requests
from datetime import datetime
from django.conf import settings

from common.bankcard import db as bank_db
from common.bankcard.model import BANK_DCT
from common.mch import handler as mch_handler
from common.timer import TIMER_EVENT_TYPE
from common.timer.handler import submit_notify_event
from common.utils import track_logging
from common.utils.exceptions import ParamError
from common.withdraw import db as withdraw_db
from common.withdraw.model import WITHDRAW_ORDER_STATUS

_LOGGER = track_logging.getLogger('withdraw')

APP_CONF = {
    # '9990002': {
    #     'API_KEY': '2b930deb7baa443da6b0d0560be03225',
    #     'GATEWAY': 'http://103.230.240.50:12345/hydra/api/withdraw/create',
    #     'QUERY_GATEWAY': 'http://103.230.240.50:12345/hydra/api/withdraw/query',
    #     'INFO': '测试环境',
    # },
    '9990001': {  # witch
        'API_KEY': '6df03bc8d7d04348a61f8042b8d457d1',
        'GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/create',
        'QUERY_GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/query',
        'INFO': '正式环境',
    },
    '9990002': {  # durota
        'API_KEY': '7f64a8d4820f43378b23ab1001887c8c',
        'GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/create',
        'QUERY_GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/query',
        'INFO': '正式环境',
    },
    '9990003': {  # 泰坦
        'API_KEY': '1172e897df4c4f5c89e3535cb80d8c55',
        'GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/create',
        'QUERY_GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/query',
        'INFO': '正式环境',
    },
    '9990004': {  # loki
        'API_KEY': '0eed9f4228404bada599a4f3ae9e2e8d',
        'GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/create',
        'QUERY_GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/query',
        'INFO': '正式环境',
    },
    '9990006': {  # RM
        'API_KEY': 'e65058eab17e4436ab5c3b58b890116c',
        'GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/create',
        'QUERY_GATEWAY': 'http://hydra.xyz115.com:12345/hydra/api/withdraw/query',
        'INFO': '正式环境',
    },
}


def _get_api_key(app_id):
    return APP_CONF[app_id]['API_KEY']


def _get_gateway(app_id):
    return APP_CONF[app_id]['GATEWAY']


def _get_query_gateway(app_id):
    return APP_CONF[app_id]['QUERY_GATEWAY']


def generate_sign(parameter, key):
    s = ''
    for k in sorted(parameter.keys()):
        s += '%s=%s&' % (k, parameter[k])
    s += 'key=%s' % key
    m = hashlib.md5()
    m.update(s.encode('utf8'))
    sign = m.hexdigest().upper()
    return sign


def create_order(order, channel):
    try:
        app_id = channel.appid
        d = {
            "mch_id": app_id,
            "mch_order_no": str(order.id),
            "player_id": str(order.user_id),
            "bank": BANK_DCT[order.pay_account_bank],
            "account_name": order.pay_account_username,
            "account_number": order.pay_account_num,
            "amount": str(order.amount),
            "notify_url": settings.HYDRA_WITHDRAW_NOTIFY_URL + app_id,
        }
        d['sign'] = generate_sign(d, _get_api_key(app_id))
        j = json.dumps(d)
        # 先设置为三方未知状态
        order.status = WITHDRAW_ORDER_STATUS.THIRD_UNKNOWN
        order.third_type = channel.id
        order.save()
        _LOGGER.info('hydra_withdraw create data: %s, %s', j, _get_gateway(app_id))
        headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
        response = requests.post(_get_gateway(app_id), headers=headers, data=j, timeout=5)
        _LOGGER.info('hydra_withdraw create rsp: %s', response.text)
        data = json.loads(response.text)
        third_id = data.get('data').get('order_id', None)
        status = data.get('data').get('status', None)
        if status == 'PROCESSING' and third_id:
            order.status = WITHDRAW_ORDER_STATUS.THIRD
            order.third_id = str(third_id)
            order.extra_info = response.content
            order.save()
            return True
        else:
            order.detail = data.get('error', '')
            order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
            order.extra_info = response.content
            order.save()
            return False
    except Exception as e:
        _LOGGER.info('hydra_withdraw create order fail: %s,%s', order.id, e)
        return False


def verify_notify_sign(params, key):
    sign = params['sign']
    params.pop('sign')
    calculated_sign = generate_sign(params, key)
    if sign.upper() != calculated_sign.upper():
        _LOGGER.info("hydra_withdraw sign: %s, calculated sign: %s", sign, calculated_sign)
        raise ParamError('sign not pass, data: %s' % params)


def check_notify_sign(request, app_id):
    api_key = _get_api_key(app_id)
    _LOGGER.info("hydra_withdraw notify body: %s", request.body)
    data = json.loads(request.body)
    verify_notify_sign(data, api_key)
    pay_id = int(data['mch_order_no'])
    if not pay_id:
        _LOGGER.error("fatal error, mch_order_no not exists, data: %s", data)
        raise ParamError('hydra_withdraw event does not contain pay ID')
    order = withdraw_db.get_order(pay_id)
    if not order or order.status != WITHDRAW_ORDER_STATUS.THIRD:
        _LOGGER.info('hydra_withdraw notify order not valid: %s ', pay_id)
        raise ParamError('hydra_withdraw event order not valid: %s' % pay_id)

    if data['status'] != 'SUCCESS' and data['status'] != 'MANUALSUCCESS':
        order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
        order.extra_info = request.body
        order.third_notify_at = datetime.utcnow()
        order.save()
        return
    order.status = WITHDRAW_ORDER_STATUS.DONE
    order.extra_info = request.body
    order.third_notify_at = datetime.utcnow()

    order.save()
    if data.get('account_number'):
        bank_db.update_real_balance(data['account_number'], data['card_balance'])
    _LOGGER.info("hydra_withdraw success mch_id: %s, order_id: %s", order.mch_id, order.id)
    notify_success, _ = mch_handler.notify_mch_withdraw(order)
    if not notify_success:
        submit_notify_event(order, TIMER_EVENT_TYPE.MCH_WITHDRAW_NOTIFY)


def query_order(order, channel):
    app_id = channel.appid
    _LOGGER.info('app_id>>>>>>>>>>>>>>>>>>>>>>>>>%s' % app_id)
    _LOGGER.info('order.id>>>>>>>>>>>>>>>>>>>>>>>>>%s' % order.id)
    d = {
        "mch_id": app_id,
        "mch_order_no": order.id,
    }
    d['sign'] = generate_sign(d, _get_api_key(app_id))
    j = json.dumps(d)
    _LOGGER.info('hydra_withdraw query_order data: %s', j)
    headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
    response = requests.post(_get_query_gateway(app_id), headers=headers, data=j, timeout=5)
    _LOGGER.info('hydra_withdraw query_order rsp: %s', response.text)
    if response.status_code != 200:
        return
    order = withdraw_db.get_order(order.id)
    data = json.loads(response.text)
    if data['status'] != 'SUCCESS':
        return
    order.status = WITHDRAW_ORDER_STATUS.DONE
    order.extra_info = response.text
    order.save()
    if data.get('account_number'):
        bank_db.update_real_balance(data['account_number'], data['card_balance'])
    _LOGGER.info("hydra_withdraw success mch_id: %s, order_id: %s", order.mch_id, order.id)
    notify_success, _ = mch_handler.notify_mch_withdraw(order)
    if not notify_success:
        submit_notify_event(order, TIMER_EVENT_TYPE.MCH_WITHDRAW_NOTIFY)
